package cn.hsa.fqz.task.service.impl;

import cn.hsa.fqz.common.utils.CHExecutor;
import cn.hsa.fqz.common.utils.page.BasePage;
import cn.hsa.fqz.common.utils.page.PageData;
import cn.hsa.fqz.task.dao.TTaskMapper;
import cn.hsa.fqz.task.dao.TTaskSqlExecuteMapper;
import cn.hsa.fqz.task.entity.TTask;
import cn.hsa.fqz.task.entity.TTaskSqlExecute;
import cn.hsa.fqz.task.enums.UserCategoryEnums;
import cn.hsa.fqz.task.service.IDataFluxService;
import cn.hsa.fqz.task.service.TTaskSqlExecuteService;
import cn.hsa.fqz.task.service.dto.LoginUserDTO;
import cn.hsa.fqz.task.service.dto.TaskSqlExecuteConfigDTO;
import cn.hsa.fqz.util.UserRegionUtils;
import cn.hsa.hsaf.core.framework.web.WrapperResponse;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 刘隽
 * @version v1.0
 * @apiNote 功能描述:()
 * @date create in 2023/3/26 4:54
 */
@Service
@Slf4j
public class TTaskSqlExecuteServiceImpl implements TTaskSqlExecuteService {

    @Autowired
    TTaskSqlExecuteMapper tTaskSqlExecuteMapper;

    @Autowired
    TTaskMapper tTaskMapper;

    @Autowired
    IDataFluxService dataFluxService;

    @Override
    public Integer insertTaskSqlExecute(TaskSqlExecuteConfigDTO taskSqlExecuteConfigDTO) {
        TTaskSqlExecute tTaskSqlExecute = new TTaskSqlExecute();
        BeanUtils.copyProperties(taskSqlExecuteConfigDTO,tTaskSqlExecute);
        tTaskSqlExecute.setStatus(1);
        tTaskSqlExecute.setTaskId(taskSqlExecuteConfigDTO.getTaskCode());
        return tTaskSqlExecuteMapper.insertSelective(tTaskSqlExecute);
    }

    @Override
    public Integer updateTaskSqlExecute(TaskSqlExecuteConfigDTO taskSqlExecuteConfigDTO) {
        TTaskSqlExecute tTaskSqlExecute = new TTaskSqlExecute();
        BeanUtils.copyProperties(taskSqlExecuteConfigDTO,tTaskSqlExecute);
        tTaskSqlExecute.setTaskId(taskSqlExecuteConfigDTO.getTaskCode());
        return tTaskSqlExecuteMapper.updateByPrimaryKeySelective(tTaskSqlExecute);
    }

    @Override
    public Integer deleteTaskSqlExecute(Integer id) {
        return tTaskSqlExecuteMapper.deleteByPrimaryKey(id);
    }

    @Override
    public Integer updateTaskSqlExecuteStatus(Integer id,Integer status) {
        return tTaskSqlExecuteMapper.changeStatus(id,status);
    }

    @Override
    public TTaskSqlExecute getOneByMenuId(String menuId) {
        return null; //tTaskSqlExecuteMapper.getOneByMenuId(menuId);
    }

    @Override
    public List<TTaskSqlExecute> getMultiSQLByTaskId(LoginUserDTO dto,String taskId) {
        List<TTaskSqlExecute> list =  tTaskSqlExecuteMapper.getMultiSQLByMenuId(taskId);
        if(dto.getRegion().equals(UserRegionUtils.GLOBAL_USER_ASCM)){
            return list;
        }else{
           List<TTaskSqlExecute> result = list.stream().filter( e -> e.getVisibled().intValue()==1).collect(Collectors.toList());
           return result;
        }
    }

    @Override
    public List<TTaskSqlExecute> getClueSqlExecuteBytTaskId(String taskId) {
        return tTaskSqlExecuteMapper.getClueSqlExecuteBytTaskId(taskId);
    }

    @Override
    public List<Map<String, Object>> getList(String host,Integer port,String passwd,String sql) {
        return dataFluxService.getTaskSqlExecuteList(host,port,passwd,sql);
    }

    @Override
    public PageData<Map<String, Object>> getPageResult(String host,Integer port,String passwd,String sql, int pageNum, int pageSize) {
        return dataFluxService.getTaskSqlExecutePageResult(host,port,passwd,sql, pageNum, pageSize);
    }

    @Override
    public String genMonitorUrl(LoginUserDTO dto,String url) {
        String result = url;
        if(dto != null){
            String region = dto.getRegion();
            result = url + "&insu_admdvs="+region;
        }
        return result;
    }

   /* public GlobalUacmInfoDTO genGlobalUacmInfo(String url){
        GlobalUacmInfoDTO dto = null;
        HttpRequest request = HttpRequest.get(url);
        HttpResponse response = request.execute();
        if(response.getStatus() == HttpStatus.HTTP_OK){
            String json = response.body();
            Map<String, String> mmp = JSON.parseObject(json, Map.class);
            if(mmp != null){
                String data = mmp.get("data");
                if(StringUtils.isNotEmpty(data)){
                    dto = JSON.parseObject(data, GlobalUacmInfoDTO.class);
                }
            }
        }
        return dto;
    }*/

    @Override
    public WrapperResponse<Object> startTaskSqlExecute(LoginUserDTO dto,String host, Integer port,String passwd, TTaskSqlExecute execute, BasePage page) {
        //UserContextFilter
        Integer taskId = Integer.valueOf(execute.getTaskId());
        TTask task = tTaskMapper.selectByPrimaryKey(taskId.intValue());
        String executeSQL = execute.getExcuteSql();
        String fxSubSql = "";
        String filterSql = "";
        StringBuffer sql = new StringBuffer("select * from ");
        sql.append(execute.getTableName()).append(" limit 1");
        List<String> columns = CHExecutor.getColumnsBySql(host,port,passwd,sql.toString());
        if(StringUtils.isNotEmpty(execute.getParamJson())&&(execute.getRisk()!=null && execute.getRisk() != -1)){
            StringBuffer buffer = new StringBuffer();
            buffer.append(" ").append(execute.getParamJson()).append(" ='").append(execute.getRisk()).append("' and ");
            fxSubSql = buffer.toString();
        }
        if(execute.getIsFilter().intValue() == 1){
            StringBuffer buffer = new StringBuffer();
            if(StringUtils.isNotEmpty(execute.getMedcCode()) && columns.contains("fixmedins_code")){
                buffer.append(" fixmedins_code = '").append(execute.getMedcCode().trim()).append("' and ");
            }
            if(StringUtils.isNotEmpty(execute.getMedcName()) && columns.contains("fixmedins_name")){
                buffer.append(" fixmedins_name like '%%").append(execute.getMedcName().trim()).append("%%' and ");
            }
            if(StringUtils.isNotEmpty(execute.getWeight()) && columns.contains("weight")){
                buffer.append(" weight = '").append(execute.getWeight().trim()).append("' and ");
            }
            filterSql = buffer.toString();
        }
        String tableSubString = executeSQL.substring(0,executeSQL.indexOf("where")+5);
        String whereSubString = executeSQL.substring(executeSQL.indexOf("where") + 5, executeSQL.length());
        executeSQL = tableSubString+fxSubSql+filterSql+whereSubString;
        //TODO:这里是针对湖北省仙桃、天门、神农架等直管部门的特殊处理
        String[] hubeiPrvs = {"429004","429005","429006","429021"};
        List<String> hubeiPrvLs = new ArrayList<>(Arrays.asList(hubeiPrvs));
        if(dto != null){
            UserCategoryEnums enums = UserRegionUtils.getUserCateEnumByAscm(dto.getRegion());
            if(enums == UserCategoryEnums.GLOBAL){
                if(task.getIsParent().intValue() == 1){
                    if(StringUtils.isNotEmpty(execute.getPrv())){
                        //如果筛选条件有筛选字段值，则赋值给当前查询
                        executeSQL = String.format(executeSQL, execute.getPrv().substring(0,2));
                    }else{
                        executeSQL = String.format(executeSQL, "");
                    }
                }else{
                    executeSQL = String.format(executeSQL, task.getPrv().substring(0,2));
                }
            }else if(enums == UserCategoryEnums.PROVINCE){
                //这里主要处理拆分子任务的子任务列表按照当前任务所属的行政区划来显示，省级处理有不同逻辑
                if(task.getIsParent().intValue() == 0 && task.getBelongTo().equals(UserCategoryEnums.PROVINCE.name())&& !hubeiPrvLs.contains(task.getPrv())){
                    executeSQL = String.format(executeSQL, task.getPrv().substring(0,4));
                }else if(task.getIsParent().intValue() == 0 && task.getBelongTo().equals(UserCategoryEnums.PROVINCE.name()) && hubeiPrvLs.contains(task.getPrv())){
                    executeSQL = String.format(executeSQL, task.getPrv());
                }else{
                    if(StringUtils.isNotEmpty(execute.getPrv())){
                        executeSQL = String.format(executeSQL, execute.getPrv().substring(0,4));
                    }else{
                        executeSQL = String.format(executeSQL, task.getPrv().substring(0,2));
                    }
                }
            }else if(enums == UserCategoryEnums.CITY){
                if(task.getIsParent().intValue() == 0 && hubeiPrvLs.contains(task.getPrv())){
                    executeSQL = String.format(executeSQL, task.getPrv());
                }else{
                    executeSQL = String.format(executeSQL, task.getPrv().substring(0,4));
                }

            }
        }
        log.info("执行ck-sql: " + executeSQL);
        if (execute.getIsPaging() == 1) {
            PageData<Map<String, Object>> result = getPageResult(host,port,passwd,executeSQL, page.getPageNum(), page.getPageSize());
            if(result != null){
                result.getRows().forEach( e -> e.put("taskCode", execute.getTaskCode()));
            }
            return WrapperResponse.success(result);
        } else {
            List<Map<String, Object>> result = getList(host,port,passwd,executeSQL);
            result.forEach(e -> e.put("taskCode",execute.getTaskCode()));
            return WrapperResponse.success(result);
        }
    }

    @Override
    public void startTaskSqlExecuteAndExport(LoginUserDTO dto, String host, Integer port,String passwd, TTaskSqlExecute execute, OutputStream os,String fileName){
        String executeSQL = execute.getExcuteSql();
        Integer taskId = Integer.valueOf(execute.getTaskId());
        TTask task = tTaskMapper.selectByPrimaryKey(taskId.intValue());
        String[] titles = execute.getTitleMap().split(",");
        List<List<String>> hs = Lists.newArrayList();
        for(String label: titles){
            hs.add(Arrays.asList(label));
        }
        if(dto != null){
            UserCategoryEnums enums = UserRegionUtils.getUserCateEnumByAscm(dto.getRegion());
            if(enums == UserCategoryEnums.GLOBAL){
                executeSQL = String.format(executeSQL, "");
            }else if(enums == UserCategoryEnums.PROVINCE){
                executeSQL = String.format(executeSQL, task.getPrv().substring(0,2));
            }else if(enums == UserCategoryEnums.CITY){
                executeSQL = String.format(executeSQL, task.getPrv().substring(0,4));
            }
        }
        List<Map<String, Object>> result = getList(host,port,passwd,executeSQL);
        List<List<Object>> xlsDatas = genXlsData(titles, result);
        EasyExcel.write(os).head(hs).sheet(fileName).doWrite(xlsDatas);
    }

    private List<List<Object>> genXlsData(String[] titles,List<Map<String, Object>> data){
        List<List<Object>> result = Lists.newArrayList();
        for (Map<String,Object> row:data) {
            List<Object> rowDatas = Lists.newArrayList();
            for(String title:titles){
                rowDatas.add(row.get(title));
            }
            result.add(rowDatas);
        }
        return result;
    }

    @Override
    public WrapperResponse<Object> executeCKDemo(String host,Integer port,String passwd,String taskId) {
        List<TTaskSqlExecute> executeList = tTaskSqlExecuteMapper.getMultiSQLByTaskId(taskId);
        TTaskSqlExecute execute = executeList.get(0);
        String executeSQL = execute.getExcuteSql();
        log.info("执行sql: " + executeSQL);
        List<Map<String, Object>> result = getList(host,port,passwd,executeSQL);
        log.info("执行CK返回结果: " + JSON.toJSONString(result));
        return WrapperResponse.success(result);
    }

    @Override
    public void exportClue(LoginUserDTO loginUser, String ckHost, Integer port,String ckPasswd, String taskCode,OutputStream os) {
       /* List<TTaskSqlExecute> list = getMultiSQLByTaskId(loginUser,taskCode);
        if(CollectionUtil.isNotEmpty(list)){
            for (TTaskSqlExecute execute:list) {
                String sheetName = execute.getTabName();
                String [] heads = execute.getTitleMap().split(",");
                List<List<String>> headList = Lists.newArrayList();

            }
        }*/
    }
}
